home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Camelot
/
Camelot 035 (1989-01)(Swedish User Group of Amiga)(SE)(PD)[m doscopy][WB].zip
/
Camelot 035 (1989-01)(Swedish User Group of Amiga)(SE)(PD)[m doscopy][WB].adf
/
Null
/
null
< prev
next >
Wrap
Text File
|
1988-12-12
|
13KB
|
432 lines
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# Makefile
# MountList
# amigaline-D1
# misc.c
# null.c
# null.doc
# null.uu
# This archive created: Mon Dec 5 17:54:58 1988
cat << \SHAR_EOF > Makefile
#########################################################################
#
# null-handler Makefile
# V 0.0 (c) Gunnar Nordmark 1988
# For Manx 3.6a
#
#########################################################################
null-handler : misc.o null.o
ln -o null-handler misc.o null.o -lc32
misc.o : misc.c
cc +L +Hnull.syms misc.c
null.o : null.c
cc +L +Inull.syms null.c
SHAR_EOF
cat << \SHAR_EOF > MountList
/*
Installs null-handler V 0.0 (C) Gunnar Nordmark
*/
null: Handler = L:null-handler
Stacksize = 500
Priority = 5
GlobVec = 1
#
SHAR_EOF
cat << \SHAR_EOF > amigaline-D1
AMIGALINE #D1, Matthew Dillon
Disconnecting a program such that you can EndCLI and also allow the
program to call Execute().
Problem:
You want to disconnect a program such that when you RUN <nil: >nil:
(using the new 1.3 RUN) you can then EndCLI the cli.
This program wants to be able to use Execute() to run other programs.
The problem is that Execute() requires a valid pr_ConsoleTask (console)
or it will freeze.
Solution: General
Run <nil: >nil: mycprogram
If using the main() entry point, you can fclose(stderr) to remove
the reference to "*". If using the _main() entry point, stdio is
not setup and thus you do not need to do this (in fact, you can't
use stdio at all without crashing the computer).
note: being able to fclose(stderr) from the main() entry point
works with Aztec C. I don't know about Lattice. Aztec always
does an Open("*", 1006) to setup stderr and this reference must
be removed.
--
At this point, you can EndCLI and the cli window goes away. However,
the 'mycprogram' cannot call Execute() or otherwise run other
external programs for two reasons:
(1) pr_ConsoleTask is still non-NULL and points to the now
defunct window (i.e. you will cause a task-held requester)
(2) you cannot set pr_ConsoleTask to NULL... Execute() does
not accept it and freezes up.
--
So, you must set pr_ConsoleTask to some other valid device. Guess
what? Any device will do except NIL: which isn't a real device. For
example, RAM: :
extern APTR DeviceProc();
proc->pr_ConsoleTask = DeviceProc("ram:");
(assuming RAM: exists)
What does this do? Any program which tries to open the console will
actually open the file "RAM:*", as in Open("RAM:*", 1006).
Unfortunetly, there is no way to place "*" in anything but the
root directory of the device. This is essentially a garbage file.
But the ultimate goal is achieved ... you can kill the CLI window
and still arbitrarily run programs from the detached program with
impunity.
The only possible problem which I have yet to test is when several
programs try to access RAM:* as their console at the same time.
Since the file is openned 1006, other programs trying to Open() it
will fail while the first programs is still running. What happens?
-Matt
SHAR_EOF
cat << \SHAR_EOF > misc.c
/*
* misc.c - support routines - Phillip Lindsay (C) Commodore 1986
* You may freely distribute this source and use it for Amiga Development -
* as long as the Copyright notice is left intact.
*
* 30-SEP-86
*
*/
#include <functions.h>
#include <stdio.h>
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <devices/console.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
extern void returnpkt();
/* returnpkt() - packet support routine
* here is the guy who sends the packet back to the sender...
*
* (I modeled this just like the BCPL routine [so its a little redundant] )
*/
void
returnpktplain(packet, myproc)
struct DosPacket *packet;
struct Process *myproc;
{
returnpkt(packet, myproc, packet->dp_Res1, packet->dp_Res2);
}
void
returnpkt(packet, myproc, res1, res2)
struct DosPacket *packet;
struct Process *myproc;
ULONG res1, res2;
{
struct Message *mess;
struct MsgPort *replyport;
packet->dp_Res1 = res1;
packet->dp_Res2 = res2;
replyport = packet->dp_Port;
mess = packet->dp_Link;
packet->dp_Port = &myproc->pr_MsgPort;
mess->mn_Node.ln_Name = (char *) packet;
mess->mn_Node.ln_Succ = NULL;
mess->mn_Node.ln_Pred = NULL;
PutMsg(replyport, mess);
}
/*
* taskwait() ... Waits for a message to arrive at your port and
* extracts the packet address which is returned to you.
*/
struct DosPacket *
taskwait(myproc)
struct Process *myproc;
{
struct MsgPort *myport;
struct Message *mymess;
myport = &myproc->pr_MsgPort;
WaitPort(myport);
mymess = GetMsg(myport);
return((struct DosPacket *)mymess->mn_Node.ln_Name);
}
/* end of misc.c */
SHAR_EOF
cat << \SHAR_EOF > null.c
/****************************************************************************
*
* null driver V0.0 (c)CopyRight 1988, Gunnar Nordmark. All Rights Reserved.
*
* null-handler Ver. 0.0 20-Jul-1988
*
* Gunnar Nordmark
* Nora strand 5
* 182 34 DANDERYD
* SWEDEN
*
* |You may freely distribute this source as long as |
* |the Copyright notice is left intact. |
***************************************************************************/
#undef BADDR
#define BADDR(x) ((APTR)((long)x << 2))
#define ACTION_FINDINPUT 1005L
#define ACTION_FINDOUTPUT 1006L
#define ACTION_END 1007L
#define DOS_FALSE 0L
#define DOS_TRUE -1L
/* My Globals */
long SysBase;
struct Process *myproc;
_main()
{
extern void returnpkt(); /* sends back the packet */
extern void returnpktplain(); /* use args in Res1 */
extern struct DosPacket *taskwait();
char *version = "Ver 0.0 (c) Gunnar Nordmark 1988";
struct DosPacket *mypkt; /* a pointer to the dos packet */
struct DeviceNode *mynode; /* our device node (parmpkt Arg3) */
struct FileHandle *fh; /* a pointer to our file handle */
long run = TRUE; /* handler main loop flag */
int null_open = 0; /* null open count */
/* Initializing the handler */
myproc = (struct Process *)FindTask(0L);
mypkt = taskwait(myproc); /* Wait for my startup message */
/* I don't need the name or extra info passed in Arg1/2 */
mynode = (struct DeviceNode *)BADDR(mypkt->dp_Arg3);
mynode->dn_Task = &myproc->pr_MsgPort;
returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
/* done initial stuff, now for some work */
while(run) {
mypkt = taskwait(myproc);
switch(mypkt->dp_Type) { /* find what action to perform */
case ACTION_FINDINPUT:
case ACTION_FINDOUTPUT:
null_open++;
fh = (struct FileHandle *)BADDR(mypkt->dp_Arg1);
fh->fh_Arg1 = mypkt->dp_Type;
fh->fh_Port = (struct MsgPort *)DOS_FALSE; /* not interactive */
returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
break;
case ACTION_READ:
returnpkt(mypkt, myproc, 0, mypkt->dp_Res2); /* zero-length=EOF */
break;
case ACTION_WRITE:
mypkt->dp_Res1 = mypkt->dp_Arg3; /* tell em we wrote them all */
returnpktplain(mypkt, myproc);
break;
case ACTION_END:
if (--null_open == 0)
run = 0;
returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
break;
default:
returnpkt(mypkt, myproc, DOS_FALSE, ERROR_ACTION_NOT_KNOWN);
break;
}
} /* end while */
mynode->dn_Task = FALSE;
}
SHAR_EOF
cat << \SHAR_EOF > null.doc
***************************************************************************
*
* null.doc 20 Nov 88 Gunnar Nordmark
*
***************************************************************************
What is null:?
Tt's a new animal that you will be glad to put in your private ZOO,
(also known as the L: directory).
"Oh no, not another silly handler!" you cry, but read on!
In the very good article by Matt Dillon, AMIGALINE#D1, that I've included
in this distribution, the problem is fully explained.
I suggests that you take a look at the file amigaline-D1 before reading
further.
As Matt explains, the NIL: device is not a "real" device. In fact it is no
device at all in the physical sense. It is just an Amiga-DOS convention
that says: If you have a process-identifier for a device, and that identifier
is just a null pointer, then that "identifier" referrs to the NIL: device.
Did you get that? I'm not surprised if you didn't, because it *is* strange.
I'll try to explain:
Every normal dos-device is a process that have an own private message-port
that is used as a comunication link between AmigaDOS and the device.
Since you must know the address of the message port of a device in order
to comunicate with it, it is a natural decision that that address also is
used as the identifier of the device.
AmigaDOS has a function called DeviceProc() that finds the address for you.
If you say port=DeviceProc("RAM:") you get the address of the message prot
of the RAM: device.
Now the strange part:
If you try port=DeviceProc("NIL:") and then sends packets to that port
you'll crash the machine instantly.
Why?
Because NIL: has *no* message-port at all.
When you have a NULL-pointer as identifier for a handler, the identifier
referrs to the NIL: device.
The *only* reason I can think of for this lack of generality, is efficiency.
You save time, becase you don't have to comunicate with a device.
You save memory, because you don't have to start a new process named NIL:.
But unfortunately this has a lot of drawbacks. Most of them are deadly.
The reason is that AmigaDOS does *not* allways check for the NIL: oddity.
Sometimes it thinks that the NULL-pointer (the NIL: identifier) is a
valid message port and merilly sends messages to it. Poof!
The solution is a new dos-device called "null:".
This is a real dos-device that has has its own message port. It just doesn't
do anything useful. It behaves exactly as NIL: i.e. you can write to it,
and read from it (then you get EOF).
The great thing about null: is that you can say
extern APTR DeviceProc();
proc->pr_ConsoleTask = DeviceProc("null:");
and you'll be able to close the console. (see amigaline-D1)
Any process can open null: as many times as it like.
And it doesn't matter if you say
Open("null:" MODE_OLDFILE);
Open("null:*" MODE_NEWFILE);
Open("null:@#$@!!" MODE_OLDFILE);
Open("null:foo.bar" MODE_OLDFILE);
everything works.
To install null: just append the included mountlist to DEVS:MountList
Copy null-handler to your L: directory and say Mount null:
I have used it for half a year now with no problems at all. I have a
written my own version of AmiCron that uses null: as pr_ConsoleTask.
That means I now have a cron-deamon that doesn't requires a window
to run!
I wan't to thank Steve Drew who wrote the aux-handler that was posted
to the net last year. I've "stolen" all the code from that handler. :-)
I hope you don't mind Steve.
- Gunnar
Gunnar Nordmark
Nora strand 5
S-182 34 DANDERYD
SWEDEN
gno@stacken.kth.se
stacken.kth.se!gno@uunet.uu.net (if the above doesn't work)
gno@SESTAK.BITNET
SHAR_EOF
cat << \SHAR_EOF > null.uu
begin 644 null-handler
M```#\P`````````#``````````(```#*````%@````$```/I````RD[Z`FY.8
M50``(&T`""\H`!`@;0`(+R@`#"\M``PO+0`(80A/[P`03EU.=4Y5__@@;0`(I
M(6T`$``,(&T`""%M`!0`$"!M``@K:``$__@@;0`(*U#__"!M``@B;0`,T_P`>
M``!<(4D`!"!M__PA;0`(``H@;?_\0I`@;?_\0J@`!"\M__PO+?_X3KH"@E!/7
M3EU.=4Y5__@@;0`(T?P```!<*TC__"\M__Q.N@)P6$\O+?_\3KH"2%A/*T#_F
M^"!M__@@*``*3EU.=4Y5_^A!^@&"*TC__"M\`````?_L0JW_Z$*G3KH""%A/]
M*4"`$B\L@!).NO^@6$\K0/_X(&W_^"`H`!SE@"M`__0@;?_T(FR`$M/\````R
M7"%)``@@;?_X+R@`$$AX__\O+(`2+RW_^$ZZ_OQ/[P`02JW_[&<``0@O+(`2&
M3KK_3EA/*T#_^"!M__@@*``(8```QE*M_^@@;?_X("@`%.6`*T#_\"!M__@B#
M;?_P(V@`"``D(&W_\$*H``0@;?_X+R@`$$AX__\O+(`2+RW_^$ZZ_I9/[P`00
M8```HB!M__@O*``00J<O+(`2+RW_^$ZZ_GA/[P`08```A"!M__@B;?_X(V@`;
M'``,+RR`$B\M__A.NOXP4$]@9%.M_^AF!$*M_^P@;?_X+R@`$$AX__\O+(`2"
M+RW_^$ZZ_C!/[P`08#Q(>`#10J<O+(`2+RW_^$ZZ_AA/[P`08"20O````%)GB
M`/]\6X!GE)"\```#EF<`_R93@&<`_R!3@&>>8,1@`/[T(&W_]$*H``A.74YU)
M5F5R(#`N,"`H8RD@1W5N;F%R($YO<F1M87)K(#$Y.#@``&%P0^R`#D7L@`ZU4
MR68.,CP`$FL(=``BPE')__PI3X`6+'@`!"E.@`Y(YX"`""X`!`$I9Q!+^@`(O
M3J[_XF`&0J?S7TYS0_H`($ZN_F@I0(`:9@PN/``#@`=.KO^48`1.NOWV4$]."
M=61O<RYL:6)R87)Y`$GY``!__DYU3OH``B)O``0L;(`.3N[^VD[Z``(@;P`$6
M+&R`#D[N_HQ,[P,```0L;(`.3N[^DD[Z``(@;P`$+&R`#D[N_H````/L````,
M`0````$```+D`````````_(```/J`````P`4`````````````````_(```/K$
(`````0```_+D:
``
end
size 908
SHAR_EOF
# End of shell archive
exit 0
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
Have five nice days.